﻿using System.Collections.Generic;
using System.Linq;
using SIG.Repository;

using SIG.Infrastructure.Logging;
using SIG.Infrastructure.Cache;
using SIG.Infrastructure.Configs;
using System.Linq.Expressions;
using System;
using SIG.Basic.Extensions;
using SIG.Resources.Admin;
using SIG.Model.Emails;
using SIG.Infrastructure.Helper;

namespace SIG.Service
{
    public class EmailAccountService: EntityService<EmailAccount>, IEmailAccountService
    {
     
        private readonly IEmailAccountRepository _emailAccountRepository;
        private readonly ILoggingService _loggingService;
        private readonly ICacheService _cacheService;

        public EmailAccountService(IEmailAccountRepository emailAccountRepository, ILoggingService loggingService, ICacheService cacheService)
            : base(emailAccountRepository, cacheService, loggingService)
        {
           
            _emailAccountRepository = emailAccountRepository;
            _loggingService = loggingService;
            _cacheService = cacheService;
        }

        


        public List<EmailAccount> GetPagedElements(int pageIndex, int pageSize, string keyword, out int totalCount)
        {

            //get list count
            var keyCount = $"{EntityNames.EmailAccount}_ListCount_{keyword}";

            var totalIQuery = _emailAccountRepository.GetAllElements();
            if (!string.IsNullOrEmpty(keyword))
                totalIQuery = totalIQuery.Where(g => g.Email.Contains(keyword));
         

            if (SettingsManager.EmailAccount.EnableCaching)
            {
                if (_cacheService.IsSet(keyCount))
                {
                    totalCount = (int)_cacheService.Get(keyCount);
                }
                else
                {
                    totalCount = totalIQuery.Count();
                    _cacheService.Set(keyCount, totalCount, SettingsManager.EmailAccount.CacheDuration);
                }
            }
            else
            {
                totalCount = totalIQuery.Count();
            }


            //get list
            var key = $"{EntityNames.EmailAccount}_List_{pageIndex}_{pageSize}_{keyword}";

            List<EmailAccount> emailAccount;
            Expression<Func<EmailAccount, bool>> filter = g => true;
            Expression<Func<EmailAccount, bool>> filterByKeyword = g => g.Email.Contains(keyword);
         

            if (!string.IsNullOrEmpty(keyword))
                filter = filter.AndAlso(filterByKeyword);
           


            if (SettingsManager.EmailAccount.EnableCaching)
            {
                if (_cacheService.IsSet(key))
                {
                    emailAccount = (List<EmailAccount>)_cacheService.Get(key);

                }
                else
                {
                    emailAccount = _emailAccountRepository.GetPagedElements(pageIndex, pageSize, (c => c.CreatedDate), filter, false).ToList();
                    _cacheService.Set(key, emailAccount, SettingsManager.EmailAccount.CacheDuration);
                }
            }
            else
            {
                emailAccount = _emailAccountRepository.GetPagedElements(pageIndex, pageSize, (c => c.CreatedDate), filter, false).ToList();
            }

            return emailAccount;

        }


        public EmailAccount SetDefault(int id)
        {
            try
            {
                var emailAccount = _emailAccountRepository.GetElementById(id);
                if (emailAccount == null)
                {                    
                    return null;
                }

                if (!emailAccount.IsDefault)
                {
                    var accounts = _emailAccountRepository.GetFilteredElements(m => m.IsDefault && m.Id != id);
                    foreach (var item in accounts)
                    {
                        item.IsDefault = false;
                        _emailAccountRepository.SetModified(item);
                    }
                    emailAccount.IsDefault = true;
                }
                else
                {
                    emailAccount.IsDefault = false;
                }
                _emailAccountRepository.SetModified(emailAccount);
                _emailAccountRepository.UnitOfWork.Commit();
                _cacheService.Invalidate(EntityNames.EmailAccount);
                _loggingService.Info(string.Format(Logs.SetDefaultEmailAccount, Site.CurrentUserName, emailAccount.Email));
                return emailAccount;
            }
            catch (Exception er)
            {
                _loggingService.Error(er.Message, er);
                return null;
            }
            
        }



    }
}
